package ${projectDomain}.adapter.system;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.unswift.annotation.api.Api;
import com.unswift.annotation.api.ApiField;
import com.unswift.annotation.api.ApiMethod;
import ${projectDomain}.adapter.BaseAdapter;
import ${projectDomain}.mapper.system.resource.SystemResourceExtendMapper;
import ${projectDomain}.mapper.system.resource.SystemResourceMapper;
import ${projectDomain}.pojo.dao.sql.Sql;
import ${projectDomain}.pojo.dao.system.resource.SystemResourceDataDo;
import ${projectDomain}.pojo.dao.system.resource.SystemResourceInsertDo;
import ${projectDomain}.pojo.dao.system.resource.SystemResourceSearchDo;
import ${projectDomain}.pojo.dao.system.resource.SystemResourceSingleDo;
import ${projectDomain}.pojo.dao.system.role.SystemRoleDataDo;
import ${projectDomain}.pojo.vo.system.resource.SystemResourceTreeVo;
import ${projectDomain}.pojo.vo.system.role.SystemRoleAuthorizeTreeVo;
import com.unswift.utils.ExceptionUtils;
import com.unswift.utils.ObjectUtils;
import com.unswift.utils.StringUtils;

@Component
@Api(value="系统资源公共服务-此bean可以被任何Service引用", author="liyunlong", date="2023-10-05", version="1.0.0")
public class SystemResourceAdapter extends BaseAdapter{
	
	@Autowired
	@ApiField("系统资源数据库操作对象")
	private SystemResourceMapper systemResourceMapper;
	
	@Autowired
	@ApiField("系统资源数据库扩展操作对象")
	private SystemResourceExtendMapper systemResourceExtendMapper;
	
	@ApiMethod(value="获取系统资源数据库操作对象", returns=@ApiField("数据库操作对象"))
	public SystemResourceMapper getMapper(){
		return systemResourceMapper;
	}
	
	@ApiMethod(value="获取系统资源模块名称", returns=@ApiField("模块名称"))
	public String getModule(){
		return "systemResource";
	}
	
	@ApiMethod(value="根据主键查询单个对象", params=@ApiField("主键"), returns=@ApiField("主键匹配的对象"))
	public SystemResourceDataDo findById(Long id){
		return this.findSingle(new SystemResourceSingleDo(id, null));
	}
	
	@ApiMethod(value="根据主键列表查询列表对象", params=@ApiField("主键列表"), returns=@ApiField("主键列表匹配的列表对象"))
	public List<SystemResourceDataDo> findByIds(List<Long> idList){
		return this.findList(new SystemResourceSearchDo(idList));
	}
	
	@ApiMethod(value="根据查询对象查询首个对象", params={@ApiField("查询对象"), @ApiField("查询到多个是否抛出异常，可以传入指定提示语，如果提示语为空，则不提示，总的提示与格式：根据%s查询到多条数据，只需要传递%s部分即可")}, returns=@ApiField("首个对象"))
	public SystemResourceDataDo findFirst(SystemResourceSearchDo search, String multipleException){
		List<SystemResourceDataDo> list=this.findList(search);
		if(ObjectUtils.isEmpty(list)){
			return null;
		}
		if(ObjectUtils.isNotEmpty(multipleException)){
			ExceptionUtils.trueException(list.size()>1, "multiple.data.found", multipleException);
		}
		return list.get(0);
    }
	
    @ApiMethod(value="根据角色集合查找关联的权限", params={@ApiField("角色集合"), @ApiField("是否管理员{1：是，0：否}")}, returns=@ApiField("拥有的权限集合"))
    public List<SystemResourceDataDo> findByRoles(List<SystemRoleDataDo> roleList, byte isAdmin){
        SystemResourceSearchDo search=new SystemResourceSearchDo();
        Sql sql=Sql.createSql();
        if(isAdmin==1) {
            search.setIsAdmin(isAdmin);
        }else {
            sql.addSelect("resource_id_");
            sql.addFrom("system_role_resource_");
            sql.addWhere(Sql.LOGIC_AND, "is_delete_", Sql.COMPARE_EQUAL, 0);
            List<Long> ids = roleList.stream().map(r -> r.getId()).collect(Collectors.toList());
            sql.addWhere(Sql.LOGIC_AND, "role_id_", Sql.COMPARE_IN, ids.toArray());
            String inSql=sql.toSql();
            sql=Sql.createSql();
            sql.addWhere(Sql.LOGIC_AND, "id_", Sql.COMPARE_IN, inSql);
        }
        sql.setBaseWhere(true);
        sql.addOrderBy("sort_", Sql.ORDER_BY_ASC);
        search.setSql(sql);
        return this.findList(search);
	}
    
    @ApiMethod(value="查找父资源，如果当前列表不包含完整路径的资源，则会补齐", params = {@ApiField("资源列表"), @ApiField("资源列表的主键集合")})
    public void findParent(List<SystemResourceDataDo> list, Set<Long> havingIdSet) {
    	if(ObjectUtils.isNotEmpty(list)) {
    		List<SystemResourceDataDo> otherList=new ArrayList<SystemResourceDataDo>();
    		Set<Long> otherIdSet=new HashSet<Long>();
    		String parentPath;
    		String[] parentPathArray;
    		long parentId;
    		for (SystemResourceDataDo resource : list) {
				if(ObjectUtils.isEmpty(resource.getParentId())) {
					continue;
				}
				parentPath=resource.getParentPath();
				parentPath=parentPath.substring(1, parentPath.length()-1);
				parentPathArray=parentPath.split("\\.");
				for (String item : parentPathArray) {
					parentId=Long.parseLong(item);
					if(!havingIdSet.contains(parentId) && !otherIdSet.contains(parentId)) {
						otherList.add(this.findById(parentId));
						otherIdSet.add(parentId);
					}
				}
			}
    		if(ObjectUtils.isNotEmpty(otherList)) {
    			list.addAll(otherList);
    		}
    	}
    }
    
    @ApiMethod(value="将资源列表解析为树结构", params = {@ApiField("资源列表"), @ApiField("父资源树"), @ApiField("展开路径")})
    public void parseResourceToTree(List<SystemResourceDataDo> list, SystemResourceTreeVo parent, String spreadPath) {
    	List<SystemResourceTreeVo> childList=new ArrayList<SystemResourceTreeVo>();
    	SystemResourceTreeVo treeNode;
    	for (SystemResourceDataDo resource : list) {
			if(ObjectUtils.isEmpty(resource.getParentId())) {
				continue;
			}
    		if(resource.getParentId().equals(parent.getId())) {
    			treeNode=new SystemResourceTreeVo(resource.getId(), resource.getName());
    			if(ObjectUtils.isNotEmpty(spreadPath) && StringUtils.contains(spreadPath, resource.getId()+"", "\\.")){
    				treeNode.setSpread(true);
    			}
    			childList.add(treeNode);
    			parseResourceToTree(list, treeNode, spreadPath);
    		}
		}
    	if(ObjectUtils.isNotEmpty(childList)) {
    		parent.setChildren(childList);
    	}
    }
    
    @ApiMethod(value="将资源列表解析为授权树结构", params = {@ApiField("资源列表"), @ApiField("父资源树"), @ApiField("选中的节点")})
    public void parseAuthorizeToTree(List<SystemResourceDataDo> list, SystemRoleAuthorizeTreeVo parent, Set<Long> checkedIds) {
    	List<SystemRoleAuthorizeTreeVo> childList=new ArrayList<SystemRoleAuthorizeTreeVo>();
    	SystemRoleAuthorizeTreeVo treeNode;
    	for (SystemResourceDataDo resource : list) {
    		if(ObjectUtils.isEmpty(resource.getParentId())) {
    			continue;
    		}
    		if(resource.getParentId().equals(parent.getId())) {
    			treeNode=new SystemRoleAuthorizeTreeVo(resource.getId(), resource.getName());
    			if(ObjectUtils.isNotEmpty(checkedIds) && checkedIds.contains(resource.getId())){
    				treeNode.setChecked(true);
    			}
    			treeNode.setSpread(true);
    			childList.add(treeNode);
    			parseAuthorizeToTree(list, treeNode, checkedIds);
    			if(ObjectUtils.isNotEmpty(treeNode.getChildren())) {
    				if(treeNode.getChildren().stream().filter(c -> !c.getChecked()).count()>0) {//如果孩子中有未被选中的，则设置选中为false，这是由layTree机制决定，用来适应前端
    					treeNode.setChecked(false);
    				}
    			}
    		}
    	}
    	if(ObjectUtils.isNotEmpty(childList)) {
    		parent.setChildren(childList);
    	}
    }
    
    @ApiMethod(value="是否存在孩子资源", params = {@ApiField("资源id")}, returns = @ApiField("是否存在孩子{true：存在，false：不存在}"))
    public boolean existsChild(long id) {
    	SystemResourceSearchDo search=new SystemResourceSearchDo();
    	search.setParentId(id);
    	int count = systemResourceMapper.findCount(search);
    	return count>0;
    }
    
    @ApiMethod(value="获取资源id的完整path", params = {@ApiField("资源id")}, returns = @ApiField("资源的完整path"))
    public String getCompletePath(Long id) {
    	if(ObjectUtils.isNotEmpty(id)){
			SystemResourceDataDo parent=this.findById(id);
			if(ObjectUtils.isNotEmpty(parent)) {
				if(ObjectUtils.isNotEmpty(parent.getParentPath())) {
					return parent.getParentPath()+parent.getId()+".";
				}else {
					return "."+parent.getId()+".";
				}
			}	
		}
    	return null;
    }
    
    @ApiMethod(value="插入数据前设置默认值", params = {@ApiField("插入的数据")})
    public void setInsertDefault(SystemResourceInsertDo insert) {
    	insert.setIsAdmin((byte)1);
    	SystemResourceSearchDo search=new SystemResourceSearchDo();
    	if(ObjectUtils.isEmpty(insert.getParentId())) {
    		Sql sql=Sql.createSql();
    		sql.addWhere(Sql.LOGIC_AND, "parent_id_", Sql.COMPARE_IS, "null");
    		search.setSql(sql);
    	}else {
    		search.setParentId(insert.getParentId());
    	}
    	insert.setSort(this.findCount(search)+1);
    	if(ObjectUtils.isEmpty(insert.getOpenInput())) {
    		insert.setOpenInput(false);
    	}
    	if(ObjectUtils.isEmpty(insert.getOpenOutput())) {
    		insert.setOpenOutput(false);
    	}
    }
    
    @ApiMethod(value="是否存在权限编码表示的权限", params = @ApiField("权限编码"), returns = @ApiField("是否存在，true：存在，false：不存在"))
    public boolean existsByAuthKey(String authKey) {
    	SystemResourceSearchDo search=new SystemResourceSearchDo();
    	search.setAuthKey(authKey);
    	return this.findCount(search)>0;
    }
}
